package com.example.springboot.file.util;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.ftp.*;

import java.io.*;
import java.net.SocketException;

/**
 * FTP操作辅助类.
 */
public class FTPHelper {
    private static final Log log = LogFactory.getLog(FTPHelper.class);
    /**
     * ftp地址.
     */
    private static String hostName = "127.0.0.1";

    /**
     * ftp端口.
     */
    private static Integer port = 21;

    /**
     * ftp登录帐号.
     */
    private static String userName = "root";

    /**
     * ftp登录密码.
     */
    private static String password = "123456";

//    static {//从系统配置文件中读取FTP服务器配置信息
//        hostName = ConfigUtil.getString("application.properties", "ftpHost");
//        port = new Integer(ConfigUtil.getString("application.properties", "ftpPort"));
//        userName = ConfigUtil.getString("application.properties", "userName");
//        password = ConfigUtil.getString("application.properties", "password");
//    }

    /**
     * 上传文件.
     *
     * @param path     FTP服务器保存目录
     * @param fileName 上传到FTP服务器上的文件名
     * @param input    要上传的文件输入流
     * @version V1.0
     */
    public static boolean uploadFile(String path, String fileName, InputStream input) {
        return uploadFile(hostName, port, userName, password, path, fileName, input);
    }

    /***
     *
     * @param url  ftp服务器地址
     * @param port  FTP服务器的端口号
     * @param username 登录到FTP服务器的账号
     * @param password 登录到FTP服务器的密码
     * @param path FTP服务器保存目录
     * @param filename  上传到FTP服务器上的文件名
     * @param input 要上传的文件输入流
     * @return
     */
    public static boolean uploadFileOtherFTP(String url, int port, String username, String password, String path, String filename, InputStream input) {
        return uploadFile(url, port, username, password, path, filename, input);
    }

    /**
     * 向FTP服务器上传文件.
     *
     * @param url      FTP服务器hostname
     * @param port     FTP服务器端口
     * @param username FTP登录账号
     * @param password FTP登录密码
     * @param path     FTP服务器保存目录
     * @param filename 上传到FTP服务器上的文件名
     * @param input    输入流
     * @return true, if successful
     */
    private static boolean uploadFile(String url, int port, String username, String password, String path, String filename, InputStream input) {
        boolean success = false;
        FTPClient ftp = new FTPClient();

        try {
            ftp.connect(url, port);//连接FTP服务器
            //如果采用默认端口，可以使用ftp.connect(url)的方式直接连接FTP服务器
            ftp.login(username, password);//登录
            int reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                return success;
            }
            ftp.changeWorkingDirectory(path);
            ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftp.storeFile(filename, input);

            input.close();
            ftp.logout();
            success = true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return success;
    }

    /**
     * 删除文件.
     *
     * @param path     the path
     * @param fileName the file name
     */
    public static boolean deleteFile(String path, String fileName) {
        return deleteFile(hostName, port, userName, password, path, fileName);
    }

    /**
     * Delete file.
     *
     * @param url      the url
     * @param port     the port
     * @param username the username
     * @param password the password
     * @param path     the path
     * @param fileName the file name
     */
    private static boolean deleteFile(String url, int port, String username, String password, String path, String fileName) {
        boolean success = false;
        FTPClient ftp = new FTPClient();

        try {
            int reply;
            ftp.connect(url, port);//连接FTP服务器
            //如果采用默认端口，可以使用ftp.connect(url)的方式直接连接FTP服务器
            ftp.login(username, password);//登录
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                return success;
            }
            ftp.changeWorkingDirectory(path);
            ftp.deleteFile(fileName);

            ftp.logout();
            success = true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return success;
    }

    /**
     * 从FTP下载文件到本地指定目录.
     *
     * @param remotePath ftp路径, 如: /ftpfolder1
     * @param fileName   要下载的文件名, 如: hello.txt
     * @return true, if successful
     */
    public static boolean downloadFile(String remotePath, String fileName, OutputStream os) {
        return downloadFile(hostName, port, userName, password, remotePath, fileName, os);
    }


    /**
     * 从ftp服务器下载非解密文件
     *
     * @param dir      服务器路径
     * @param fileName 服务器文件名
     * @param output   输出流
     * @param addr     ftp地址
     * @param usr      ftp用户名
     * @param pass     ftp密码
     * @return
     * @throws Exception
     */
    public static boolean downFileToFTPUnlock(String dir, String fileName, OutputStream output, String addr, String usr, String pass) throws Exception {
        boolean upload = false;
        InputStream input = null;
        String hostname = hostName;//ftp地址
        if (addr != null)
            hostname = addr;
        Integer ports = port;
        int port = 21;//ftp端口号
        if (ports != null) {
            port = ports;
        }
        //ftp用户名
        String uid = userName;
        if (uid == null || "".equals(uid)) {
            uid = "lenovo";
        }
        if (usr != null && !"".equals(usr))
            uid = usr;
        //ftp密码
        String pwd = password;
        if (pwd == null || "".equals(pwd)) {
            pwd = "lenovo";
        }
        if (pass != null && !"".equals(pass))
            pwd = pass;
        FTPClient ftp = new FTPClient();
        try {
            ftp.connect(hostname, port);
            int reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                log.error("无法连接FTP服务器,server=" + hostname + ",port=" + port);
                ftp.disconnect();
                throw new Exception("无法连接FTP服务器.");
            }
        } catch (IOException e) {
            throw new Exception("连接FTP服务器出错", e);
        }
        log.info("连接FTP服务器,server=" + hostname + ",port=" + port);
        //进行登陆
        try {
            if (!ftp.login(uid, pwd)) {
                log.info("uid,user=" + uid + ",password=" + pwd);
                ftp.logout();
                throw new Exception("无法登陆FTP服务器");
            }
        } catch (FTPConnectionClosedException ftpEx) {
            throw new Exception("登陆FTP服务器错误:连接已经断开");
        } catch (IOException e) {
            throw new Exception("登陆FTP服务器错误:IO错误");
        }
        log.info("登陆FTP服务器,server=" + hostname + ",port=" + port);
        //设置传输模式
        try {
            ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftp.enterLocalPassiveMode();

        } catch (Exception e) {
            e.getMessage();
        }
        try {
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            ftp.setBufferSize(4 * 1048);
            ftp.setControlEncoding("UTF-8");
            String rootDir = "";
            ftp.changeWorkingDirectory(rootDir);
            if (dir != null && dir.indexOf(";") != -1) {
                String[] dirs = dir.split(";");
                int length = dirs.length;
                int i = 0;
                while (i < length) {
                    String tmp = dirs[i];
                    ftp.makeDirectory(tmp);
                    ftp.changeWorkingDirectory(tmp);
                    i++;
                }
            } else {
                ftp.makeDirectory(dir);
                ftp.changeWorkingDirectory(dir);
            }

            upload = ftp.retrieveFile(fileName, output);
            if (!upload) {//判断是否下载成功Herb
                if (fileName.indexOf(".") != -1) {//判断是否存在 Herb
                    String file = fileName.substring(0, fileName.indexOf("."));//截取文件的名字去掉文件的后缀
                    upload = ftp.retrieveFile(file, output);//重新下载
                }
            }
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            ftp.disconnect();
            if (output != null) {
                output.close();
                output = null;
            }
        }
        return upload;
    }

    // 不加密删除
    public static boolean deleteFileToFTPUnlock(String dir, String fileName)
            throws Exception {
        boolean upload = false;
        FTPClient ftp = new FTPClient();
        try {
            ftp.connect(hostName, port);
            //如果采用默认端口，可以使用ftp.connect(url)的方式直接连接FTP服务器
            ftp.login(userName, password);//登录
            int reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                return false;
            }
            // 设置传输模式
            ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftp.enterLocalPassiveMode();
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            ftp.setBufferSize(4 * 1048);
            ftp.setControlEncoding("UTF-8");
            boolean isFile = fileName != null && !"".equals(fileName);
            if (dir != null && dir.indexOf("/") != -1) {
                String[] dirs = dir.split("/");
                int length = dirs.length;
                int i = 0;
                while (i < length) {
                    String tmp = dirs[i];
                    if (i != length - 1) {
                        ftp.makeDirectory(tmp);
                        ftp.changeWorkingDirectory(tmp);
                    } else {
                        if (isFile) {
                            ftp.makeDirectory(tmp);
                            ftp.changeWorkingDirectory(tmp);
                        }
                    }
                    dir = tmp;
                    i++;
                }
            } else {
                ftp.makeDirectory(dir);
                ftp.changeWorkingDirectory(dir);
            }
            if (isFile) {
                upload = ftp.deleteFile(fileName);
            } else {
                upload = ftp.removeDirectory(dir);
                upload = true;
            }
            ftp.logout();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            ftp.disconnect();
        }
        return upload;
    }

    /**
     * 文件下载方法包含解密程序
     *
     * @param dir      文件服务器路径
     * @param fileName 文件名
     * @param output   输出流（用于下载）
     * @param addr     ftp地址
     * @param usr      ftp用户
     * @param pass     ftp密码
     * @return
     * @throws Exception
     */
    public static boolean downFileToFTP(String dir, String fileName, OutputStream output, String addr, String usr, String pass) throws Exception {
        boolean upload = false;
        InputStream input = null;
        String hostname = hostName;//ftp地址
        if (addr != null)
            hostname = addr;
        Integer ports = port;
        int port = 21;//ftp端口号
        if (ports != null) {
            port = ports;
        }
        //ftp用户名
        String uid = userName;
        if (uid == null || "".equals(uid)) {
            uid = "lenovo";
        }
        if (usr != null && !"".equals(usr))
            uid = usr;
        //ftp密码
        String pwd = password;
        if (pwd == null || "".equals(pwd)) {
            pwd = "lenovo";
        }
        if (pass != null && !"".equals(pass))
            pwd = pass;
        FTPClient ftp = new FTPClient();
        try {
            ftp.connect(hostname, port);
            int reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                log.error("无法连接FTP服务器,server=" + hostname + ",port=" + port);
                ftp.disconnect();
                throw new Exception("无法连接FTP服务器.");
            }
        } catch (IOException e) {
            throw new Exception("连接FTP服务器出错", e);
        }
        log.info("连接FTP服务器,server=" + hostname + ",port=" + port);
        //进行登陆
        try {
            if (!ftp.login(uid, pwd)) {
                log.info("uid,user=" + uid + ",password=" + pwd);
                ftp.logout();
                throw new Exception("无法登陆FTP服务器");
            }
        } catch (FTPConnectionClosedException ftpEx) {
            throw new Exception("登陆FTP服务器错误:连接已经断开");
        } catch (IOException e) {
            throw new Exception("登陆FTP服务器错误:IO错误");
        }
        log.info("登陆FTP服务器,server=" + hostname + ",port=" + port);
        //设置传输模式
        try {
            ftp.setFileType(FTPClient.BINARY_FILE_TYPE);
            ftp.enterLocalPassiveMode();

        } catch (Exception e) {
            e.getMessage();
        }
        try {
            ftp.setFileType(FTP.BINARY_FILE_TYPE);
            ftp.setBufferSize(4 * 1048);
            ftp.setControlEncoding("UTF-8");
            String rootDir = "";
            ftp.changeWorkingDirectory(rootDir);
            if (dir != null && dir.indexOf(";") != -1) {
                String[] dirs = dir.split(";");
                int length = dirs.length;
                int i = 0;
                while (i < length) {
                    String tmp = dirs[i];
                    ftp.makeDirectory(tmp);
                    ftp.changeWorkingDirectory(tmp);
                    i++;
                }
            } else {
                //转移到FTP服务器目录
                ftp.makeDirectory(dir);
                ftp.changeWorkingDirectory(dir);
            }
            input = ftp.retrieveFileStream(fileName);
            //ftp.logout();
        } catch (SocketException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            ftp.disconnect();
        }
        return upload;
    }

    /**
     * 从FTP服务器下载文件.
     *
     * @param url        FTP服务器hostname
     * @param port       FTP服务器端口
     * @param username   FTP登录账号
     * @param password   FTP登录密码
     * @param remotePath FTP服务器上的相对路径
     * @param fileName   要下载的文件名
     */
    private static boolean downloadFile(String url, int port, String username, String password, String remotePath, String fileName, OutputStream os) {
        boolean success = false;
        FTPClient ftp = new FTPClient();
        try {
            ftp.connect(url, port);
            //如果采用默认端口，可以使用ftp.connect(url)的方式直接连接FTP服务器
            ftp.login(username, password);//登录
            int reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                return success;
            }
            ftp.changeWorkingDirectory(remotePath);//转移到FTP服务器目录
            ftp.setFileType(FTPClient.BINARY_FILE_TYPE);//以二进制传输文件数据

            FTPFile[] fs = ftp.listFiles();
            for (FTPFile ff : fs) {
                if (ff.getName().equals(fileName)) {
                    ftp.retrieveFile(ff.getName(), os);
                    if (os != null) {
                        os.flush();
                        os.close();
                    }
                }
            }
            ftp.logout();
            success = true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return success;
    }

    /**
     * Creates the dir.
     *
     * @param url               the url
     * @param port              the port
     * @param username          the username
     * @param password          the password
     * @param remoteRootPath    the remote root path
     * @param remoteDynamicPath the remote dynamic path
     */
    private static boolean createDir(String url, int port, String username, String password, String remoteRootPath, String remoteDynamicPath) {

        boolean success = false;
        FTPClient ftp = new FTPClient();
        try {
            int reply;
            ftp.connect(url, port);
            //如果采用默认端口，可以使用ftp.connect(url)的方式直接连接FTP服务器
            ftp.login(username, password);//登录
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                return success;
            }
            //转移到FTP服务器目录
            ftp.changeWorkingDirectory(remoteRootPath);

            String[] dirs = remoteDynamicPath.split(";");
            for (String s : dirs) {
                ftp.makeDirectory(s);
                ftp.changeWorkingDirectory(s);
            }
            ftp.logout();
            success = true;
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return success;
    }

    /**
     * 在指定FTP目录中动态创建多层目录(如果目录已存在, 无影响).
     *
     * @param remoteRootPath    当前要创建目录的根目录
     * @param remoteDynamicPath 要创建的文件夹(可以是多层文件夹, 以分号分隔. 如: test1;test2;test3)
     */
    public static boolean createDir(String remoteRootPath, String remoteDynamicPath) {
        return createDir(hostName, port, userName, password, remoteRootPath, remoteDynamicPath);
    }

    public static void main(String[] args) {

        String path ="upload";
        String fileName="C:\\Users\\Administrator\\Desktop\\图片\\1F519142103-1.jpg";
        InputStream input = null;
        try {
            input = new FileInputStream(new File(fileName));
            FTPHelper.uploadFile(path,"1F519142103.jpg",input);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }
}
